#include "Import/BDFImport/BulkData/Element/CTRIA6Parser.h"

#include <algorithm>
#include <cstdint>
#include <iostream>

#include "Utility/Logging/SGLogger.h"

#include "DataStructure/Input/Element/CTRIA6Data.h"

#include "DBManager/DBServiceFactory.h"
#include "DBManager/IService/Input/Element/IElementService.h"

#include "Import/BDFImport/BDFParserBase.h"

BULKDATA_ENTRY_PARSER_REG (CTRIA6);

using namespace SG::DBManager;
using namespace SG::Import;
using namespace SG::DataStructure;

enum CTRIA6key : std::uint8_t
{
    CTRIA6KEY_EID = 2,
    CTRIA6KEY_PID = 3,  // Property identification number of a PSHELL, PCOMP, PCOMPG or PLPLANE entry. (Integer > 0; Default = EID)
    CTRIA6KEY_G1  = 4,  // Grid point identification numbers of connection points. (Integers > 0, all unique)
    CTRIA6KEY_G2  = 5,
    CTRIA6KEY_G3  = 6,
    CTRIA6KEY_G4  = 7,
    CTRIA6KEY_G5  = 8,
    CTRIA6KEY_G6  = 9,
    CTRIA6KEY_THETAorMCID =
        12,  // Material property orientation angle in degrees. THETA is ignored for hyperelastic elements. (Real; Default = 0.0)
    CTRIA6KEY_ZOFFS = 13,   // Offset from the surface of grid points to the element reference plane. See Remark  3.
                           // ZOFFS is ignored for hyperelastic elements. (Real)
    
    CTRIA6KEY_T1    = 14,  // Membrane thickness of element at grid points G1 through G3. If “TFLAG” zero or
                           // blank, then Ti are actual user specified thickness. (Real > 0.0 or blank, not all zero. See
                           // Remark  4. for default.) If “TFLAG” one, then the Ti are fraction relative to the T value
                           // of the PSHELL. (Real > 0.0 or blank; not all zero. Default = 1.0) Ti are ignored for
                           // hyperelastic elements.
    CTRIA6KEY_T2 = 15,
    CTRIA6KEY_T3 = 16,
    CTRIA6KEY_TFLAG = 17,  // An integer flag, signifying the meaning of the Ti values. (Integer 0, 1, or blank)
};

SG::DataStructure::Common::Status BDF::BULKDATA::ParseCTRIA6 (const std::shared_ptr<SG::DBManager::DBServiceFactory>& dbServiceFactory,
                                                              std::vector<std::string>&                               dividedEntryInfo)
{
    // 创建临时的CTRIA6数据对象
    SG::DataStructure::FEM::CTRIA6Data tempCTRIA6;

    // TODO(bug 001) 正确填写m_dominId，当前默认赋值为1
    tempCTRIA6.m_domainId = 1;

    // 初始化当前词条的索引为1
    int curIDKey = 1;

    // 遍历解析后的词条信息
    for (auto curStrKey : dividedEntryInfo)
    {
        // 跳过空白词条
        bool const isEmpty = is_all_space (curStrKey);
        if (isEmpty)
        {
            curIDKey++;
            continue;
        }

        // 判断当前词条是否为浮点数，并转换为科学计数法
        bool const isFloat = covertToScientificNotation (curStrKey);

        // 根据当前词条的索引，解析不同的字段
        switch (curIDKey)
        {
        // 解析元素ID (EID)
        case CTRIA6KEY_EID:
            tempCTRIA6.m_id = convertToI64 (curStrKey);
            // 如果PID没有指定，则默认PID等于EID
            tempCTRIA6.m_pId = tempCTRIA6.m_id;
            break;

        // 解析属性ID (PID)
        case CTRIA6KEY_PID:
            tempCTRIA6.m_pId = convertToI64 (curStrKey);
            break;

        // 解析节点G1
        case CTRIA6KEY_G1:
            tempCTRIA6.m_g[0] = convertToI64 (curStrKey);
            break;

        // 解析节点G2
        case CTRIA6KEY_G2:
            tempCTRIA6.m_g[1] = convertToI64 (curStrKey);
            break;

        // 解析节点G3
        case CTRIA6KEY_G3:
            tempCTRIA6.m_g[2] = convertToI64 (curStrKey);
            break;

        // 解析节点G4
        case CTRIA6KEY_G4:
            tempCTRIA6.m_g[3] = convertToI64 (curStrKey);
            break;

        // 解析节点G5
        case CTRIA6KEY_G5:
            tempCTRIA6.m_g[4] = convertToI64 (curStrKey);
            break;            

        // 解析节点G6
        case CTRIA6KEY_G6:
            tempCTRIA6.m_g[5] = convertToI64 (curStrKey);
            break;        

        // 解析角度THETA或坐标系ID(MCID)
        case CTRIA6KEY_THETAorMCID:
            if (!isFloat)
            {
                tempCTRIA6.m_mcId = convertToI64 (curStrKey);
            }
            else
            {
                tempCTRIA6.m_theta = convertToReal (curStrKey);
            }
            break;

        // 解析Z方向偏移(ZOFFS)
        case CTRIA6KEY_ZOFFS:
            tempCTRIA6.m_zoffs = convertToReal (curStrKey);
            break;

        // 解析T1厚度
        case CTRIA6KEY_T1:
            tempCTRIA6.m_ti[0] = convertToReal (curStrKey);
            break;

        // 解析T2厚度
        case CTRIA6KEY_T2:
            tempCTRIA6.m_ti[1] = convertToReal (curStrKey);
            break;

        // 解析T3厚度
        case CTRIA6KEY_T3:
            tempCTRIA6.m_ti[2] = convertToReal (curStrKey);
            break;

        // 解析厚度标志(TFLAG)
        case CTRIA6KEY_TFLAG:
            tempCTRIA6.m_tflag = convertToI64 (curStrKey);
            break;

        // 其他未知字段
        default:
            break;
        }

        // 增加当前词条的索引
        curIDKey++;
    }

    // 将解析后的CTRIA6数据添加到数据库
    return dbServiceFactory->get<IElementService> ()->Add (tempCTRIA6);
}
